前面在AppController下建立User
@Post()
create(@Body() userDTO: UserDTO){
return `使用者:${userDTO.username}已建立`;
}
從Client傳遞使用者資料至nest並沒有任何驗證,client即便輸入不符合DTO屬性格式,nest也會接受,因為沒有寫驗證的程式碼。
假設欄位限制為
nest.js裡有Pipe搭配class-validator、class-transformer套件來實現驗證Client欄位輸入的資訊
流程為
在UserDTO.ts裡使用class-validator相關Validation Decorators,例如@IsString()為必須為字串
建立UserDTOValidationPipe實作PipeTransform介面,在transform方法裡撰寫驗證的程式碼
註冊至Module底下的providers
到對應的方法宣告@UsePipes並指定UserDTOValidationPipe
測試
修改UserDTO.ts如下
import { IsEmail, IsString, Length } from 'class-validator';
export class UserDTO {
@IsString()
@Length(0, 10, { //可以指定錯誤訊息
message: '長度需要小於十',
})
username: string;
@IsEmail()
email: string;
}
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from '@nestjs/common';
import { plainToClass } from 'class-transformer';
import { validate } from 'class-validator';
@Injectable()
export class UserDTOValidationPipe implements PipeTransform<any> {
async transform(value, { metatype }: ArgumentMetadata) {
if (!metatype || !this.toValidate(metatype)) {
return value;
}
const object = plainToClass(metatype, value);
const errors = await validate(object);
if (errors.length > 0) {
throw new BadRequestException(errors);
}
return value;
}
private toValidate(metatype): boolean {
const types = [String, Boolean, Number, Array, Object];
return !types.find((type) => metatype === type);
}
}
利用nest cli新增shared.module.ts
nest g module shared
import { Module } from '@nestjs/common';
import { UserDTOValidationPipe } from './pipes/userDTOValidation.pipe';
@Module({
providers: [
UserDTOValidationPipe,
],
})
export class SharedModule {}
將ShardModule import 到 AppModule,讓AppModule下的Controller可以使用Shared Module的Pipe
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { SharedModule } from './shared/shared.module';
@Module({
imports: [SharedModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
@Post()
@UsePipes(UserDTOValidationPipe)
create(@Body() userDTO: UserDTO){
return `使用者:${userDTO.username}已建立`;
}
username輸出超過10個字元,Email格式不正確,nest.js回傳Error Object,在SPA網頁上可以顯示驗證錯誤訊息